Skip to content

Add functions to get temporary URLs for files #1780

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

chimnayajith
Copy link
Contributor

@chimnayajith chimnayajith commented Aug 2, 2025

Implement getFileTemporaryUrl and tryGetFileTemporaryUrl to access user-uploaded files without requiring authentication. The temporary URLs remain valid for 60 seconds and provide a secure way to share files without exposing API keys.

This uses the GET /user_uploads/{realm_id}/{filename} endpoint that returns a URL allowing immediate access without requiring authentication.

Requested in #1144 (comment)

Will be needed for #42 and #43

@gnprice
Copy link
Member

gnprice commented Aug 3, 2025

Cool. This will also be the main ingredient in fixing #1732, which is an issue in our upcoming milestone M6.

(I haven't yet looked at this implementation at all.)

///
/// This endpoint is documented in the OpenAPI description:
/// https://github.com/zulip/zulip/blob/main/zerver/openapi/zulip.yaml
/// under the name `get_file_temporary_url`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// under the name `get_file_temporary_url`.
/// under the name `get-file-temporary-url`.

I couldn't find a match of get_file_temporary_url searching in zulip.yaml, but searching get-file-temporary-url has a match.

@@ -327,6 +327,51 @@ class UploadFileResult {
Map<String, dynamic> toJson() => _$UploadFileResultToJson(this);
}

/// Get a temporary, authless partial URL to a realm-uploaded file.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: commit summary line

- api [nfc]: Add functions to get temporary URLs for files
+ api: Add routes getFileTemporaryUrl and tryGetFileTemporaryUrl

The two functions in the commit introduce new behavior (new API calls and logic), so it's not an NFC commit. Also, good to mention the routes introduced in the summary line.

});
});

test('returns temporary URL for valid realm file', () {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test and the remaining test blocks in the group require an indentation.

realmUrl: connection.realmUrl);

check(result).isNull();
// Verify no API calls were made
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Verify no API calls were made
// Verify no API calls were made.

or

Suggested change
// Verify no API calls were made
// verify no API calls were made

Either complete a sentence that starts with a capital letter by adding a period at the end, or start it with a lowercase letter and omit the period. 🙂
(the same applies to the one below this)

test('returns null for non-realm URL', () {
return FakeApiConnection.with_((connection) async {
final result = await tryGetFileTemporaryUrl(connection,
url: Uri.parse('https://example.com/image.jpg'),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
url: Uri.parse('https://example.com/image.jpg'),
url: Uri.parse('https://example.com/user_uploads/123/testfile.jpg'),

The URL provided is both non-realm URL and a non-matching URL, but the test case is only about non-realm URL, so it's good to adjust it to only what the test case is about. That way, it's easy to validate it against what the test case claims.

Copy link
Collaborator

@sm-sayedi sm-sayedi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chimnayajith for taking care of this. A few comments above!

@chrisbobbe
Copy link
Collaborator

@chimnayajith please post here when you've pushed a revision for Sayed's review; thank you :)

Implement `getFileTemporaryUrl` and `tryGetFileTemporaryUrl` to access
user-uploaded files without requiring authentication. The temporary URLs
remain valid for 60 seconds and provide a secure way to share files
without exposing API keys.

This uses the GET `/user_uploads/{realm_id}/{filename}` endpoint that
returns a URL allowing immediate access without requiring authentication.

Requested in zulip#1144 (comment)
@chimnayajith
Copy link
Contributor Author

@sm-sayedi Pushed a revision. PTAL.

@sm-sayedi
Copy link
Collaborator

Thanks, LGTM. Marking for Chris's review.

@sm-sayedi sm-sayedi requested a review from chrisbobbe August 24, 2025 09:26
@sm-sayedi sm-sayedi added the maintainer review PR ready for review by Zulip maintainers label Aug 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintainer review PR ready for review by Zulip maintainers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants